# BSD3.0
# cili@163.com

from socket import gethostbyname,gethostname
import tkinter as tk
from tkinter import messagebox
from tkinter import ttk

import http.server
import socketserver
import socket
import threading
import sys

class MyTCPServer:
    def __init__(self,port,request_handler):
        self.server_thread = None
        for tport in range(port,60000):
            try:
                self.server = socketserver.ThreadingTCPServer(('', tport), request_handler)
                self.port = tport
                break
            except socket.error as e:
                pass
        self.server.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    def start(self):
        if self.server:
            server_thread = threading.Thread(target=self.server.serve_forever)
            server_thread.daemon = True
            server_thread.start()

    def stop(self):
        if self.server is not None:
            stop_thread = threading.Thread(target=self.stop_server_thread)
            stop_thread.start()

    def stop_server_thread(self):
        if self.server is not None:
            self.server.shutdown()
            self.server.server_close()
            if self.server_thread: self.server_thread.join(2)
            self.server_thread = None
            self.server = None

class SimpleHandler(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/':
            self.path = '/index.html'
        self.path = f'web/{self.path}'
        super().do_GET()

    def send_error(self, code, message=None, explain=None):
        self.send_response(code)
        self.send_header('Content-type', 'text/html; charset=utf-8')
        self.end_headers()
        message = "<html><body><h1>网站正在建设中</h1></body></html>" if self.path.endswith(
            'index.html') else f"Error {code}: {message or http.client.responses[code]}"
        self.wfile.write(message.encode('utf-8'))

class WebServerApp:
    def __init__(self, root):
        self.root = root
        self.port = tk.IntVar(value=8080)
        self.ip = gethostbyname(gethostname())
        self.server = MyTCPServer(self.port.get(), SimpleHandler)
        self.server.start()
        self.port.set(self.server.port)

        self.root.title("简易万维网服务器")
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
        self.root.resizable(False, False)
        self.create_widgets()
        self.center_windows()
        self.url_text.focus()
        self.url_text.select_range(0, tk.END)

    def create_widgets(self):
        self.ip_label = ttk.Label(self.root, text="IP地址：", anchor='e')
        self.ip_label.grid(row=0, column=0, sticky="e", padx=5, pady=5)
        self.ip_text = ttk.Label(self.root, width=30, text=self.ip)
        self.ip_text.grid(row=0, column=1, sticky="w", padx=5, pady=5)

        self.port_label = ttk.Label(self.root, text="服务端口：", anchor='e')
        self.port_label.grid(row=1, column=0, sticky="e", padx=5, pady=5)
        self.port_text = ttk.Label(self.root, textvariable=self.port, width=30)
        self.port_text.grid(row=1, column=1, sticky="w", padx=5, pady=5)

        self.status_label = ttk.Label(self.root, text="访问地址：", anchor='e')
        self.status_label.grid(row=2, column=0, sticky="e", padx=5, pady=5)

        self.url_text = ttk.Entry(self.root, width=40)
        self.url_text.insert(tk.END, f"http://{self.ip}:{self.port.get()}")
        self.url_text.state(['readonly'])
        self.url_text.grid(row=2, column=1, sticky="w", padx=5,pady=5)

        tips=ttk.Label(self.root,text='1. 利用访问地址即可访问网站。',anchor= 'e')
        tips.grid(row=3, column=0, columnspan=2, sticky="w", padx=5, pady=5)
        tips = ttk.Label(self.root, text='2. 网站应保存在Web文件中。', anchor='e')
        tips.grid(row=4, column=0, columnspan=2, sticky="w", padx=5)

    def center_windows(self):
        self.root.update()
        screen_width = self.root.winfo_screenwidth()
        screen_height = self.root.winfo_screenheight()
        window_width = self.root.winfo_width()
        window_height = self.root.winfo_height()
        x_coordinate = int((screen_width / 2) - (window_width / 2))
        y_coordinate = int((screen_height / 2) - (window_height / 2))
        self.root.geometry("+{}+{}".format(x_coordinate, y_coordinate))

    def on_closing(self):
        sys.exit()


if __name__ == "__main__":
    root = tk.Tk()
    app = WebServerApp(root)
    root.mainloop()
